<template>
  <div>
    <div class="yaml-editor">
      <codemirror
        ref="codeMirrorRef"
        :value="content"
        :merge="uiState.showDiff"
        :options="options"
      />
    </div>
    <div v-if="!readonly">
      <el-upload :before-upload="readFile" class="upload" action="">
        <el-button>{{ $t("commons.button.upload") }}</el-button>
      </el-upload>
      <el-button
        v-if="!uiState.showDiff && props.edit"
        :disabled="content === oldContent"
        class="upload"
        @click="onHandleShowDiff"
      >
        {{ $t("commons.button.show_diff") }}
      </el-button>
      <el-button
        v-if="uiState.showDiff"
        class="upload"
        @click="uiState.showDiff = false"
      >
        {{ $t("commons.button.continue_edit") }}
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
// import "codemirror/addon/lint/lint.css"
// // import "codemirror/lib/codemirror.css"
// import "codemirror/theme/ayu-dark.css"
// import "codemirror/mode/yaml/yaml"
// import "codemirror/addon/lint/lint"
// import "codemirror/addon/lint/yaml-lint"
// import "codemirror/addon/fold/foldgutter.css"
// import "codemirror/addon/fold/foldcode"
// import "codemirror/addon/fold/foldgutter"
// import "codemirror/addon/fold/brace-fold"
// import "codemirror/addon/fold/comment-fold"
// import "codemirror/addon/fold/indent-fold"
// import "codemirror/addon/search/searchcursor"
// import "codemirror/addon/search/search"
import "js-yaml";
// import "codemirror/addon/merge/merge"
// import "codemirror/addon/merge/merge.css"
import DiffMatchPatch from "diff-match-patch";
import { reactive, ref } from "vue";
import { objectToYaml } from "../../../utils";

//@ts-ignore
window.diff_match_patch = DiffMatchPatch;
//@ts-ignore
window.DIFF_DELETE = -1;
//@ts-ignore
window.DIFF_INSERT = 1;
//@ts-ignore
window.DIFF_EQUAL = 0;

const value = defineModel<any>("value");
type Prop = {
  readonly?: boolean;
  edit?: boolean;
};

const props = withDefaults(defineProps<Prop>(), {
  readonly: false,
  edit: false
});

const codeMirrorRef = ref();

const oldContent = ref();
const content = ref();

const options = ref({
  value: "",
  mode: "yaml",
  theme: "ayu-dark",
  lineNumbers: true,
  tabSize: 4,
  foldGutter: true,
  lineWrapping: true,
  gutters: [
    "CodeMirror-linenumbers",
    "CodeMirror-foldgutter",
    "CodeMirror-lint-markers"
  ],
  lint: true,
  origLeft: null,
  orig: "",
  connect: "align",
  collapseIdentical: true,
  highlightDifference: true
});

const uiState = reactive({
  changed: false,
  showDiff: false
});

const foldCode = (key: string) => {
  const cursor = codeMirrorRef.value?.getSearchCursor(key);
  if (cursor && cursor.findNext()) {
    codeMirrorRef.value?.foldCode(cursor.form());
  }
};

const readFile = file => {
  const fr = new FileReader();
  fr.readAsText(file);
  fr.onload = () => {
    codeMirrorRef.value?.setValue(fr.result);
  };
  return false;
};

const onHandleShowDiff = () => {
  uiState.showDiff = !uiState.showDiff;
  options.value.value = content.value;
  options.value.orig = oldContent.value;
};

const initData = (data: any) => {
  if (!data) {
    return;
  }
  content.value = objectToYaml(data);
  oldContent.value = objectToYaml(data);

  foldCode("managedFields");
  codeMirrorRef.value?.setOption("readOnly", props.readonly);
};
</script>

<style lang="scss">
.yaml-editor {
  height: 100%;
  position: relative;
}

.CodeMirror {
  border: 1px solid #eee;
  height: auto;
  min-height: 300px;
}

.CodeMirror-merge {
  border: 1px solid #eee;
  height: auto;
  min-height: 300px;
}

.CodeMirror-merge-r-chunk {
  background: #3c3c3ce3;
}

.CodeMirror-merge-r-chunk-end {
  border-bottom: unset;
}

.CodeMirror-merge-r-chunk-start {
  border-top: unset;
}

.upload {
  display: inline-block;
  float: left;
  margin-top: 10px;
}
</style>
